import image.ImageCapturer;
import image.ImageCapturerImpl;
import mllib.Classifier;
import image.ImageFixer;
import common.ConstVars;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;

public class ImageClassifier extends JFrame {
	protected Button capture, classify;
	protected JLabel picture;
    private ImageCapturer ic;
    private double[] vector;
    private static String tempOutput = "temp.jpg";
    private static String tempIcon = "tempIcon.jpg";
    int imageCounter = 0;
    private Classifier classifier;

    /**
     * Creates an image classifier
     * @param filename the file containing all the training set data
     */
	public ImageClassifier(String filename)
  {
    this(filename, null);
  }

	public ImageClassifier(String filename, String pcaFilename)
    {
        super("Image Classifier");

        KeyListener kl = new MyKeyListener();

        System.out.println("CREATING CLASSIFIER...");
        classifier = new Classifier(filename, pcaFilename,Classifier.GEstimator,  50);
        System.out.println("CLASSIFIER FINISHED");
        setSize(750, 500);

/*		classify = new Button("Classify");
        capture = new Button("Capture");
        classify.addKeyListener(kl);
        capture.addKeyListener(kl);*/
		
		ButtonListener b = new ButtonListener();
		
/*  		classify.addActionListener(b);
        capture.addActionListener(b);*/
		
        setLayout(new BorderLayout());

        this.addKeyListener(kl);
        this.setFocusable(true);
//        add(capture, BorderLayout.NORTH);
        picture = new JLabel("Capture an Image");
        picture.addKeyListener(kl);
        picture.setFocusable(true);
        add(picture, BorderLayout.CENTER);
//        add(classify, BorderLayout.SOUTH);

        ic = new ImageCapturerImpl();

		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setVisible(true);
	}

  private void updateImage(String fileName)
  {
      ImageIcon i = (ImageIcon)picture.getIcon();
      if(i != null)
        i.getImage().flush();
      picture.setIcon(new ImageIcon(fileName));
      this.repaint();
  }

    private class MyKeyListener implements KeyListener {

        public void keyTyped(KeyEvent e) {
          System.out.println(e);
            if(e.getKeyCode() == KeyEvent.VK_W) {
                takePhoto();
            }
            else if(e.getKeyCode() == KeyEvent.VK_S) {
                classifyPhoto();
            }
        }

        public void keyPressed(KeyEvent e) {
            //To change body of implemented methods use File | Settings | File Templates.
        }

        public void keyReleased(KeyEvent e) {
            //To change body of implemented methods use File | Settings | File Templates.
        }
    }

	private class ButtonListener implements ActionListener {
		public void actionPerformed(ActionEvent evt) {
		    String arg = evt.getActionCommand();
            if(arg.equals("Classify")) {
                classifyPhoto();
            }
            else {
                takePhoto();
			}
		}
	}

    public String classifyPhoto() {
        String guess = classifier.identify(vector);
//        try {
//        if(!"Other_other".equals(guess))
//            ImageFixer.save(ImageFixer.getImageFromFile(tempOutput), "imagetestdata/"+ guess + imageCounter++ + ".jpg");
//        } catch (Exception e) {}
        picture.setText(guess);
        picture.updateUI();
        return guess;
    }

    public void takePhoto() {
        ic.captureImage(tempOutput);
        BufferedImage bimage = null;
        try {
            bimage = ImageFixer.getImageFromFile(tempOutput);
            ImageFixer.drawFeaturePoints(bimage);
            ImageFixer.save(bimage, tempIcon);
            updateImage(tempIcon);
            picture.setText("");
            picture.updateUI();
        }
        catch(Exception e) {
            System.err.println("IO with image error; frame skipped");
        }
        try {
            bimage = ImageFixer.getImageFromFile(tempOutput);
            bimage = ImageFixer.cropToFace(bimage);
            bimage = ImageFixer.resizeImage(bimage, ConstVars.IMG_DIM, ConstVars.IMG_DIM);
            vector =  new double[ConstVars.IMG_DIM_2];
            ImageFixer.imageToVector(bimage, vector);
        }
        catch(Exception e) {
          System.err.println("IO error with image; not analyzed");
        }
        return;
    }
	
	public static void main(String args[]) {
        ImageClassifier tic = null;
        if(args.length == 0)
        {
          System.err.println("usage: trainging_data [pca_file]");
          System.exit(1);
        }
        else if(args.length == 1)
        {
          tic = new ImageClassifier(args[0]);
        }
        else
        {
            System.out.println("CREATING IMAGE CLASSIFIER WITH PCA...");
            tic = new ImageClassifier(args[0], args[1]);
        }
        tic.setVisible(true);
        String person;
        while(true){
            tic.takePhoto();
            tic.classifyPhoto();
        }
    }
}
